#define GLEW_STATIC
#include <GL/glew.h>
#include "game.h"
#include "settings.h"
#include "keyboard.h"
#include "log.h"

cGame::cGame()
{
    m_frame = 0;
    m_frameTime = 0;
    m_lastTime = 0;

    m_pause = false;
    m_loop = true;
}

cGame::~cGame()
{
    m_timer.stop();
}

static cGame& cGame::instance()
{
    static cGame instance;
    return instance;
}

bool cGame::init()
{
    initSettings();
    glewExperimental = GL_TRUE;

    if (SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO) < 0)
    {
        log(LOG_ERROR, "Unable to init SDL: %s\n", SDL_GetError());
        return false;
    }
    else
        log(LOG_INFO, "Using SDL %d.%d\n", SDL_MAJOR_VERSION, SDL_MINOR_VERSION);

    if (!m_graphics.createWindow())
    {
        log(LOG_ERROR, "Unable to create a window, try changing resolution in config\n");
        return false;
    }

    GLenum err = glewInit();
    if (err != GLEW_OK)
    {
         log(LOG_ERROR, "Unable to init GLEW: %s\n", glewGetErrorString(err));
         return false;
    }
    else
        log(LOG_INFO, "Using GLEW %s\n", glewGetString(GLEW_VERSION));

    if (!m_graphics.initGL())
    {
        log(LOG_ERROR, "Failed to init GL settings\n");
        return false;
    }
    else
        log(LOG_INFO, "Inited GL settings\n");

    log(LOG_INFO, "Game loaded!\n");
    //loadMedia();

    return true;
}

void cGame::loop()
{
    startMap();

    m_timer.start();
    m_startTime = m_timer.getTicks();
    m_lastTime = m_startTime;

    m_loop = true;

    while (m_loop)
    {
        keyboard::update();

        if (keyboard::keyUp("KEY_ESCAPE"))
            m_loop = false;

        if (keyboard::keyDown("KEY_FULLSCREEN"))
            m_graphics.setVsync(!m_graphics.vsyncEnabled());

        if (keyboard::keyDown("KEY_PAUSE"))
            m_pause = !m_pause;

        m_frameTime = m_timer.getTicks() - m_lastTime;

        m_map->tick(m_frameTime);

        m_lastTime = m_timer.getTicks();

        m_graphics.render();
        m_frame++;

        if (m_frame % 100 == 0)
            log(LOG_DEBUG, "fps: %f\n", 1000 * (float)m_frame / (m_timer.getTicks() - m_startTime));
    }

    endMap();
}

void cGame::shutdown()
{
    log(LOG_INFO, "Shutting down\n");
    SDL_Quit();
}

void cGame::startMap()
{
    m_map = new cMap();
}

void cGame::endMap()
{
    delete m_map;
}

void cGame::test()
{
    log(LOG_DEBUG, "asd\n");
}

cMap* cGame::currentMap()
{
    return m_map;
}

bool cGame::isPaused()
{
    return m_pause;
}
